                          Assembler coding - Lesson 9

                                   Interrupts                                
                                                                             
    An Interrupt is a process that INTERRUPTS the processor's operation at   
    that instant in time to execute another piece of code.                   
                                                                             
    For example assume that you were running some software that monitored    
    100 hotel rooms to see if the fire alarm or something had gone off. If   
    one had you execute some more code to ring the fire department. This     
    type of coding is SLOW, it is termed POLLING. Here we are continually    
    checking each room to see if the alarm has been set (It uses all the     
    processing time, and we can't do anything else).                         
                                                                             
    A better way to do this would be to have the alarms wired to the         
    processors interrupt pin. An Interrupt then occurs which halts processor 
    operation at that point in time (Note that before an Interrupt occured,  
    the processor could have been doing something else as it was not tied up 
    POLLING). Now the interrupt has occured and the processor calls an       
    Interrupt Routine, this routine could then check which hotel alarm has   
    been set and act accordingly.                                            
                                                                             
    Of course this method is external, i.e. hardwired, we will be generating 
    interrupts internally, but you can see now what an interrupt is.         
                                                                             
    I mentioned that when an interrupt is generated it executes an Interrupt 
    Routine at that instant in time. This means it leaves whatever code it   
    was doing and jumps to the interrupt routine. When the interrupt routine 
    is finished, you Return from the Interrupt Routine back to where you     
    left the original code. The interrupt routine may well include code that 
    overwrites your values in the accumulator and X & Y registers. You       
    therefore need to place these values in a special place in memory called 
    the STACK. You place these values on the STACK at the very beginning of  
    the interrupt routine, and then the very last thing you do in your       
    interrupt routine is to take the values back out of STACK and place them 
    back into the registers where they came from.                            
                                                                             
    The STACK is 256 bytes long and is located in memory at address 0100 Hex 
    to 01FF Hex. The STACK is termed :-                                      
                                                                             
      LIFO - Last In First Out                                               
                                                                             
    This means that whatever you place in the stack last, will be taken out  
    first.                                                                   
                                                                             
    For example, here's the beginning and end of a interrupt routine :-      
                                                                             
      PHA - Here we push the accumulator onto the stack                      
                                                                             
      TXA - Here we transfer the X reg to Accumulator                        
                                                                             
      PHA - Push accumulator onto stack                                      
                                                                             
      TYA - Transfer Y reg to Accumulator                                    
                                                                             
      PHA - Push accumulator onto stack                                      
                                                                             
      ...                                                                    
                                                                             
      ...                                                                    
                                                                             
      PLA - Pull value from stack into accumulator                           
                                                                             
      TAY - Transfer accumulator to Y register                               
                                                                             
      PLA - Pull value from stack into accumulator                           
                                                                             
      TAX - Transfer accumulator to X register                               
                                                                             
      PLA - Pull value from stack into accumulator                           
                                                                             
    Can you see that we must do it this way otherwise all the values would   
    be in the wrong registers.                                               
                                                                             
    Also remember that this is only needed if you are writing over your      
    original register values. This method can also be used in other parts of 
    your program to keep track of your register values.                      
                                                                             
                                                                             
                                                                             
    Ok, back to actual interrupts.                                           
                                                                             
    There are 4 types of interrupts on the C64, these are :-                 
                                                                             
      RASTER - (This is what we are going to be using)                       
                                                                             
      SPRITE to BACKGROUND collision                                         
                                                                             
      SPRITE to SPRITE collision                                             
                                                                             
      LIGHT PEN                                                              
                                                                             
    Each of these interrupts is located at 53273 or $D019.                   
                                                                             
      Raster - BIT 0                                                         
                                                                             
      Sprite to Background - BIT 1                                           
                                                                             
      Sprite to Sprite - BIT 2                                               
                                                                             
      Light Pen - BIT 4                                                      
                                                                             
      BIT 7 of $D019 (53273) is the IRQ and is set for all interrupts        
                                                                             
    The C64 generates an interrupt 60 times a second, this is used to check  
    the keyboard etc., and when an interrupt has occured the processor       
    checks Bit 4 of the status register which is the BRK flag. If this is    
    set then the program jumps to vector at locations $0316 & $0317. If BIT  
    4 is not set then the interrupt is an IRQ (Interrupt Request) and then   
    the program jumps to the vector stored at locations $0314 & $0315.       
                                                                             
    A vector is the location which holds the address of where your Interrupt 
    Routine is located at. You will notice that there are 2 vector           
    addresses. One holds the Low Byte of your interrupt routine, whilst the  
    other holds the high byte.                                               
                                                                             
    Where :-                                                                 
                                                                             
    $0314 = Low Byte                                                         
                                                                             
    $0315 = High Byte                                                        
                                                                             
    Example                                                                  
                                                                             
    The location $0314 Holds the Value 00 (Hex)                              
                                                                             
    The location $0315 Holds the value 10 (Hex)                              
                                                                             
    The location of your interrupt routine would therefore placed at $1000   
    (Hex) or 4096 (Decimal)                                                  
                                                                             
    (NOTE - You place the interrupt routine code at this location yourself)  
                                                                             
                                                                             
                                                                             
    Raster Lines                                                             
                                                                             
    Your TV or monitor screen is composed of SCAN lines (raster lines). This 
    is the way the picture is produced.                                      
                                                                             
    The monitor or TV is really a CRT (Cathode Ray Tube) which has a         
    Phosphorus coated screen. At the back of the screen is an Electron Gun   
    which fires electrons along the Tube to the screen. An electron hitting  
    the phosphorus screen causes visible light (what you see). The gun is    
    fired across your screen and then moves slightly down, across again,     
    then down etc, etc. The gun is firing continuously each place where it   
    fires is one pixel. The amount the gun moves down is 0-262 on PAL TV's   
    and 0-312 on NTSC. This value is greater than 255 and so the register    
    $D012 is used to hold the lower 8 bits, while $D011 holds the 9th bit.   
    All this happens so fast that the screen looks like it does to you.      
                                                                             
                                                                             
                                                                             
    Ok enough talk lets do an example program. You will learn more by        
    looking and then trying the code for yourself.                           
                                                                             
    This example will split the screen into 3 parts. Each part will have a   
    different background and border colour so you can see whats happened.    
                                                                             
      10 ORG 8192                                                            
                                                                             
      20 SEI                                                                 
                                                                             
      30 LDA #147                                                            
                                                                             
      40 JSR $FFD2                                                           
                                                                             
      50 LDA #$7F                                                            
                                                                             
      60 STA $DC0D                                                           
                                                                             
      70 LDA #00                                                             
                                                                             
      80 STA $D012                                                           
                                                                             
      90 STA IRQCOUNT                                                        
                                                                             
      100 LDA (UPARROW)IRQ - YOU JUST TYPE THE UP ARROW                      
                                                                             
      110 STA $0315                                                          
                                                                             
      120 LDA #IRQ                                                           
                                                                             
      130 STA $0314                                                          
                                                                             
      140 LDA $D01A                                                          
                                                                             
      150 ORA #01                                                            
                                                                             
      160 STA $D01A                                                          
                                                                             
      165 CLI                                                                
                                                                             
      170 LOOP JMP LOOP                                                      
                                                                             
      180 IRQ LDA #01                                                        
                                                                             
      190 STA $D019                                                          
                                                                             
      200 LDA $D011                                                          
                                                                             
      210 AND #$7F                                                           
                                                                             
      220 STA $D011                                                          
                                                                             
      230 LDA IRQCOUNT                                                       
                                                                             
      240 BEQ INT1                                                           
                                                                             
      250 CMP #01                                                            
                                                                             
      260 BEQ INT2                                                           
                                                                             
      270 JMP RESET                                                          
                                                                             
      280 INT1 LDA #100                                                      
                                                                             
      290 STA $D012                                                          
                                                                             
      300 INC IRQCOUNT                                                       
                                                                             
      310 LDA #02                                                            
                                                                             
      320 STA 53280                                                          
                                                                             
      330 STA 53281                                                          
                                                                             
      340 JMP $EA31                                                          
                                                                             
      350 INT2 LDA #200                                                      
                                                                             
      360 STA $D012                                                          
                                                                             
      370 INC IRQCOUNT                                                       
                                                                             
      380 LDA #03                                                            
                                                                             
      390 STA 53280                                                          
                                                                             
      400 STA 53281                                                          
                                                                             
      410 JMP $FEBC                                                          
                                                                             
      420 RESET LDA #00                                                      
                                                                             
      430 STA IRQCOUNT                                                       
                                                                             
      440 STA $D012                                                          
                                                                             
      450 LDA #05                                                            
                                                                             
      460 STA 53280                                                          
                                                                             
      470 STA 53281                                                          
                                                                             
      480 JMP $FEBC                                                          
                                                                             
      490 IRQCOUNT DFB 00                                                    
                                                                             
    Right lets have a look at the explanation :-                             
                                                                             
                                                                             
                                                                             
    10 ORG 8192 - Where to place in memory                                   
                                                                             
    20 SEI - This disables interrupts until we are ready to accept them by   
    setting up first                                                         
                                                                             
    30 LDA #147                                                              
                                                                             
    40 JSR $FFD2 - Clear Screen                                              
                                                                             
    50 LDA #$7F                                                              
                                                                             
    60 STA $DC0D - These turn off CIA interrupts (BIT 7 = 0)                 
                                                                             
    70 LDA #00                                                               
                                                                             
    80 STA $D012 - Set first raster at 0                                     
                                                                             
    90 STA IRQCOUNT - Set a flag to hold count so we know where we are       
                                                                             
    100 LDA (UPARROW)IRQ                                                     
                                                                             
    110 STA $0315 - Set the high byte of the interrupt routine called IRQ    
                                                                             
    120 LDA #IRQ                                                             
                                                                             
    130 STA $0314 - Set the low byte of the interrupt routine                
                                                                             
    140 LDA $D01A                                                            
                                                                             
    150 ORA #01                                                              
                                                                             
    160 STA $D01A - The last 3 lines enable raster interrupts (BIT 0 = 1)    
                                                                             
    165 CLI - Enable interrupts again cos we have now got setup (            
                                                                             
    170 LOOP JMP LOOP - Continuous Loop                                      
                                                                             
    This next part is the Interrupt Routine called IRQ (this is the address  
    stored at the vectors $0314 & $0315)                                     
                                                                             
    180 IRQ LDA #01                                                          
                                                                             
    190 STA $D019 - These 2 lines cause the raster interrupt (BIT 0 = 1)     
                                                                             
    200 LDA $D011                                                            
                                                                             
    210 AND #$7F                                                             
                                                                             
    220 STA $D011 - These last 3 clear the 8th BIT of the raster             
                                                                             
    230 LDA IRQCOUNT - Here we find the position of the program to go to     
                                                                             
    240 BEQ INT1 - Branch here if IRQCOUNT = 0                               
                                                                             
    250 CMP #01                                                              
                                                                             
    260 BEQ INT2 - Branch here if IRQCOUNT = 1                               
                                                                             
    270 JMP RESET - If IRQCOUNT is not equal 0 or 1 then jump to RESET       
                                                                             
    280 INT1 LDA #100 - The first position                                   
                                                                             
    290 STA $D012 - We set the raster position to 100 down the screen        
                                                                             
    300 INC IRQCOUNT - +1 to the flag (now = 1)                              
                                                                             
    310 LDA #02                                                              
                                                                             
    320 STA 53280                                                            
                                                                             
    330 STA 53281 - Change the colours of the background and borders to RED  
                                                                             
    340 JMP $EA31 - Jump to ROM (Main entry IRQ point)                       
                                                                             
    350 INT2 LDA #200 - Position 2                                           
                                                                             
    360 STA $D012 - We have set the raster to occur at position 200 down the 
    screen                                                                   
                                                                             
    370 INC IRQCOUNT - +1 to flag again (now = 2)                            
                                                                             
    380 LDA #03                                                              
                                                                             
    390 STA 53280                                                            
                                                                             
    400 STA 53281 - Change colours of border & background                    
                                                                             
    410 JMP $FEBC - Jump to ROM (Exit Interrupt)                             
                                                                             
    420 RESET LDA #00 - 3rd position                                         
                                                                             
    430 STA IRQCOUNT - And so we now reset the flag to zero as all positions 
    are done                                                                 
                                                                             
    440 STA $D012 - We also set the raster back to zero                      
                                                                             
    450 LDA #05                                                              
                                                                             
    460 STA 53280                                                            
                                                                             
    470 STA 53281 - Again we change the colours of the border and background 
                                                                             
    480 JMP $FEBC - And again jump to ROM (Exit Interrupt)                   
                                                                             
    490 IRQCOUNT DFB 00 - This is the memory location for IRQCOUNT           
                                                                             
                                                                             
                                                                             
    Well that about raps it up. Now you can see that on each of those        
    positions you could have 8 sprites in each, and different direction      
    scrolls or whatever takes your fancy.                                    
                                                                             
    We will do some kind of program like that later, but in the next lesson  
    we will learn how to do raster colour bars.                              

   [IMG]_[IMG]
